<template>
  <el-drawer
    :title="`分配【${role.roleName}】权限`"
    v-model="visible"
    size="400px"
    :before-close="close"
    direction="rtl"
  >
    <div>
      <el-tree show-checkbox :data="menuList" ref="treeRef" node-key="id">
        <template #default="{ node, data }">
          <span class="custom-tree-node">
            <!-- 一、二级菜单类型显示自定义图标 -->
            <SvgIcon
              v-if="[1, 2].includes(node.level)"
              :name="data.meta.icon"
            />
            <!-- 三级菜单显示`菜单`或`按钮`图标 -->
            <el-icon v-else>
              <ele-Menu v-if="data.type == 1" />
              <ele-SwitchButton v-else-if="data.type == 2" />
            </el-icon>
            <span class="ml10">{{ data.meta.title }}</span>
          </span>
        </template>
      </el-tree>
    </div>
    <template #footer>
      <el-button @click="submitForm" type="primary">提交</el-button>
      <el-button @click="handleCheckAll">全选/不选</el-button>
      <el-button @click="handleExpand">展开/收起</el-button>
      <el-button @click="close">取消</el-button>
    </template>
  </el-drawer>
</template>

<script lang="ts" setup>
import { reactive, ref, toRefs, onMounted } from "vue";
import { getList } from "@/api/system/menu";
import { getMenuIdsByRoleId, saveRoleMenu } from "@/api/system/role";
import { ElNotification } from "element-plus";

const state = reactive({
  visible: false,
  checked: false,
  expandAll: false, //控制展开的状态
  role: {
    roleName: "",
    id: "",
  },
  menuList: [],
  //   树的回显数据的保存
  menuIds: [],
});
const { visible, role, menuList } = { ...toRefs(state) };
const treeRef = ref();
onMounted(() => {});
const open = async (role) => {
  state.role = role;
  state.visible = true;
  await loadMenuList();
  // 查询角色拥有的菜单ids
  await loadRoleMenuIds();
  await checkOldMenuNode();
};
const loadMenuList = async () => {
  const res = await getList();
  if (res.code === 200) {
    state.menuList = res.data;
  }
};
// 提交
const submitForm = async () => {
  // 收集选中的菜单ids
  const checkedMenuIds = treeRef.value.getCheckedKeys();
  // 收集半选中(父节点）的菜单id
  const parentIds = treeRef.value.getHalfCheckedKeys();
  // 合并所有上面获取的菜单ids
  const menuIds = parentIds.concat(checkedMenuIds);
  const res = await saveRoleMenu(state.role.id, menuIds);
  if (res.code === 200) {
    ElNotification.success({
      message: "操作成功",
    });
    close();
  }
};
const handleCheckAll = () => {
  // 全选/全不选  全打勾
  state.checked = !state.checked;
  if (state.checked) treeRef.value.setCheckedNodes(state.menuList);
  // 取消全选
  else treeRef.value.setCheckedNodes([]);
};
const handleExpand = () => {
  // 展开收起
  state.expandAll = !state.expandAll;
  changeTreeNodeStatus(treeRef.value.store.root);
};
const changeTreeNodeStatus = (node: any) => {
  console.log(node, "点击折叠展开");
  // node 底下有expanded属性控制展开折叠
  node.expanded = state.expandAll;
  for (let i = 0; i < node.childNodes.length; i++) {
    node.childNodes[i].expanded = state.expandAll; //每一层都让expandAll统一
    // 查询当前节点是否还有子节点
    if (node.childNodes[i].childNodes.length > 0) {
      // 递归
      changeTreeNodeStatus(node.childNodes[i]);
    }
  }
};
const close = () => {
  // 取消
  state.visible = false;
  //   清空数据操作
  state.menuIds = []; //树回显的数据
  state.menuList = [] //树的数据
  state.checked = false  //全选操作
  state.expandAll = false //折叠操作
};
// 树的回显的数据接口
const loadRoleMenuIds = async () => {
  const { id } = state.role;
  const res = await getMenuIdsByRoleId(id);
  if (res.code === 200) {
    state.menuIds = res.data;
  }
};
// 树的回显
const checkOldMenuNode = () => {
  const { menuIds } = state;
  menuIds.forEach((id) => {
    // 获取节点对象
    const node = treeRef.value.getNode(id);
    // console.log(node, "node的数据");
    // 根据节点对象，判断是否为子节点，是子节点则勾选，不是则不勾选
    if (node && node.isLeaf) {
      // 选中打勾的方法
      treeRef.value.setChecked(id, true);
    }
  });
};

defineExpose({
  open,
});
</script>
<style lang="scss" scoped>
.custom-tree-node {
  font-size: 14px;
  display: flex;
  align-items: center;
  padding-left: 10px;
}
</style>
